import pandas as pd
from statsmodels.tsa.arima.model import ARIMA
from datetime import timedelta, datetime
from rest_framework import status
from decimal import Decimal
from rest_framework.decorators import action
from django_filters import rest_framework as filters
from django.db.models import Sum
from django.utils import timezone
from common.viewset import CustomViewBase
from common.utils.response import JsonResponse
from device.filters import deviceInfoFilter, channelInfoFilter, temperatureInfoFilter, warningSettingInfoFilter, \
    warningDeviceInfoFilter
from device.models import deviceInfo, channelInfo, temperatureInfo, warningSettingInfo, warningDeviceInfo
from device.serializers import deviceInfoSerializer, channelInfoSerializer, temperatureInfoSerializer, \
    warningSettingInfoSerializer, warningDeviceInfoSerializer


class deviceInfoViewset(CustomViewBase):
    queryset = deviceInfo.objects.all().order_by("-id")
    serializer_class = deviceInfoSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = deviceInfoFilter


class channelInfoViewset(CustomViewBase):
    queryset = channelInfo.objects.all().order_by("id")
    serializer_class = channelInfoSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = channelInfoFilter


class temperatureInfoViewset(CustomViewBase):
    queryset = temperatureInfo.objects.all().order_by("-id")
    serializer_class = temperatureInfoSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = temperatureInfoFilter

    @action(methods=['get'], detail=False)
    def getRealData(self, request):
        this_tongdao_tmp = request.GET.get("this_tongdao", 1)

        latest_order_time = temperatureInfo.objects.filter(belong_channel__id=this_tongdao_tmp).last()
        if latest_order_time:
            real_time_data = temperatureInfo.objects.filter(
                belong_channel__id=this_tongdao_tmp,
                order_time=latest_order_time.order_time
            ).values('id', 'belong_channel', 'meter_address', 'temperature_info', 'order_time')
        else:
            real_time_data = []

        return JsonResponse(data=real_time_data, code=status.HTTP_200_OK, msg='数据获取成功', status=status.HTTP_200_OK)

    @action(methods=['get'], detail=False)
    def getAverageData(self, request):
        this_tongdao_tmp = request.GET.get("this_tongdao", 1)
        average_data = []
        now = timezone.now()
        one_minute_ago = now - timedelta(minutes=5)

        count = 0
        warningObj = warningSettingInfo.objects.get(belong_channel__id=this_tongdao_tmp)
        temperatureOrderObj = temperatureInfo.objects.filter(belong_channel__id=this_tongdao_tmp).last()
        temperatureObj = temperatureInfo.objects.filter(belong_channel__id=this_tongdao_tmp, order_time=temperatureOrderObj.order_time)

        for item in warningObj.all_district_details.all():
            district_data = {}

            # 筛选出 meter_address 在 item.meter_start 和 item.meter_end 之间的温度信息
            temperatures_count = temperatureObj.filter(
                meter_address__gte=item.meter_start,
                meter_address__lte=item.meter_end
            ).count()
            temperatures_sum = temperatureObj.filter(
                meter_address__gte=item.meter_start,
                meter_address__lte=item.meter_end
            ).aggregate(num=Sum('temperature_info'))

            if temperatures_count == 0:
                average_temp = 0
            else:
                average_temp = (temperatures_sum['num'] / temperatures_count).quantize(Decimal('0.00'))

            district_data['district_name'] = item.name
            district_data['average'] = average_temp
            average_data.append(district_data)

        return JsonResponse(data=average_data, code=status.HTTP_200_OK, msg='数据获取成功', status=status.HTTP_200_OK)

    @action(methods=['get'], detail=False)
    def getPredictData(self, request):
        belong_channel = request.GET.get("belong_channel", 1)
        order_time = request.GET.get("order_time", '')
        # order_time_after = request.GET.get("order_time_after", '')
        # order_time_before = request.GET.get("order_time_before", '')

        warning_message = ''
        warningObj = warningSettingInfo.objects.get(belong_channel__id=belong_channel)

        predict_data_temp = []
        temperatureObj = temperatureInfo.objects.filter(belong_channel__id=belong_channel, order_time=order_time)
        all_value = []
        for item in temperatureObj:
            temperature_info = float(item.temperature_info)
            all_value.append(temperature_info)

        # 生成一个示例时间序列数据集
        data = {'date': pd.date_range(start='2024-01-01', periods=len(all_value), freq='D'),
                'value': all_value}
        df = pd.DataFrame(data)
        df.set_index('date', inplace=True)
        # 拟合 ARIMA 模型
        model = ARIMA(df['value'], order=(1, 2, 1))
        model_fit = model.fit()
        model_fit.summary()
        # 做出预测
        forecast = model_fit.forecast(steps=len(all_value))
        key = 0
        warning_res = ''
        for item in temperatureObj:
            predict_data_obj = {}
            predict_data_obj['meter_address'] = item.meter_address
            predict_temperature_info = round(float(forecast[key]), 2)
            predict_data_obj['temperature_info'] = predict_temperature_info
            warning_value = float(warningObj.constant_threshold)
            # predict_temperature_info 测量值
            # warning_value 规定值
            print('predict_temperature_info:', predict_temperature_info, type(predict_temperature_info))
            print('constant_threshold:', warning_value, type(warning_value))
            # 正常数据
            if float(predict_temperature_info) <  float(warning_value):

                warning_message = '根据预测，所有监测电缆的温度无明显异常变化，无异常温度点，电缆温度处于稳定的温度范围,'
                if warningObj.devict_type == 'device':
                    warning_res = '设备运行稳定，继续保持设备的健康运行，并进行定期检查'

                elif warningObj.devict_type == 'pidai':
                    warning_res = '皮带运行良好，未发现过热情况，继续保持设备的健康运行，建议进行定期检查'

                elif warningObj.devict_type == 'people':
                    warning_res = '当前环境温度适宜，未发现影响身体健康的情况，建议持续保持当前环境的稳定，为生产人员提供健康舒适的工作环境'
            else:
                # 异常数据
                if warningObj.devict_type == 'device':
                    warning_res = '根据预测，' + warningObj.device_info + '设备预计会出现故障，建议巡检人员对设备进行检查保养'
                elif warningObj.devict_type == 'pidai':
                    warning_res = '根据预测皮带的温度预计会超上限，可能会因温度过高产生过热或爆炸的情况，建议监测、巡检人员到现场进行必要的降温处理'
                elif warningObj.devict_type == 'people':
                    warning_res = '根据预测环境温度温度急剧上升，可能会导致现场工作人员工作环境对身体产生不良的影响，如中暑等健康问题，请建议监测巡检人员对现场工作人员进行远程提醒'
            predict_data_temp.append(predict_data_obj)
            key += 1
        predict_data = {}
        predict_data['data'] = predict_data_temp

        warning_message = warning_message + warning_res
        predict_data['message'] = warning_message
        return JsonResponse(data=predict_data, code=status.HTTP_200_OK, msg='数据获取成功', status=status.HTTP_200_OK)


class warningSettingInfoViewset(CustomViewBase):
    queryset = warningSettingInfo.objects.all().order_by("id")
    serializer_class = warningSettingInfoSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = warningSettingInfoFilter


class warningDeviceInfoViewset(CustomViewBase):
    queryset = warningDeviceInfo.objects.all().order_by("-id")
    serializer_class = warningDeviceInfoSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = warningDeviceInfoFilter